package meiyunting.shiwuzhaoling.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 负载均衡测试控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/loadbalancer")
public class LoadBalancerTestController {

    @Autowired
    private LoadBalancerClient loadBalancerClient;
    
    @Autowired
    private DiscoveryClient discoveryClient;
    
    @Autowired
    private RestTemplate restTemplate;
    
    /**
     * 测试负载均衡 - 直接展示服务实例选择
     * @param serviceId 服务ID
     * @return 选择的服务实例信息
     */
    @GetMapping("/choose/{serviceId}")
    public Map<String, Object> chooseService(@PathVariable String serviceId) {
        Map<String, Object> result = new HashMap<>();
        
        // 使用负载均衡器选择一个服务实例
        ServiceInstance instance = loadBalancerClient.choose(serviceId);
        
        if (instance == null) {
            result.put("status", "error");
            result.put("message", "未找到服务: " + serviceId);
            return result;
        }
        
        result.put("status", "success");
        result.put("serviceId", serviceId);
        result.put("instanceId", instance.getInstanceId());
        result.put("host", instance.getHost());
        result.put("port", instance.getPort());
        result.put("uri", instance.getUri().toString());
        result.put("metadata", instance.getMetadata());
        
        log.info("选择服务实例: {}, URI: {}", instance.getInstanceId(), instance.getUri());
        
        return result;
    }
    
    /**
     * 测试负载均衡 - 连续多次选择，观察分配情况
     * @param serviceId 服务ID
     * @param times 选择次数
     * @return 每次选择的服务实例信息
     */
    @GetMapping("/test/{serviceId}/{times}")
    public Map<String, Object> testLoadBalancer(
            @PathVariable String serviceId, 
            @PathVariable int times) {
        Map<String, Object> result = new HashMap<>();
        List<Map<String, Object>> selections = new ArrayList<>();
        
        // 获取可用实例
        List<ServiceInstance> instances = discoveryClient.getInstances(serviceId);
        
        if (instances.isEmpty()) {
            result.put("status", "error");
            result.put("message", "未找到服务: " + serviceId);
            return result;
        }
        
        // 统计实例被选择的次数
        Map<String, Integer> selectionCount = new HashMap<>();
        for (ServiceInstance instance : instances) {
            selectionCount.put(instance.getInstanceId(), 0);
        }
        
        // 连续选择多次
        for (int i = 0; i < times; i++) {
            ServiceInstance instance = loadBalancerClient.choose(serviceId);
            if (instance == null) {
                continue;
            }
            
            Map<String, Object> selection = new HashMap<>();
            selection.put("round", i + 1);
            selection.put("instanceId", instance.getInstanceId());
            selection.put("host", instance.getHost());
            selection.put("port", instance.getPort());
            
            selections.add(selection);
            
            // 更新计数
            selectionCount.put(instance.getInstanceId(), selectionCount.getOrDefault(instance.getInstanceId(), 0) + 1);
        }
        
        result.put("status", "success");
        result.put("serviceId", serviceId);
        result.put("totalInstances", instances.size());
        result.put("selections", selections);
        result.put("statistics", selectionCount);
        
        return result;
    }
    
    /**
     * 获取所有可用的服务实例
     * @param serviceId 服务ID
     * @return 所有可用实例信息
     */
    @GetMapping("/instances/{serviceId}")
    public List<Map<String, Object>> getServiceInstances(@PathVariable String serviceId) {
        List<Map<String, Object>> result = new ArrayList<>();
        
        List<ServiceInstance> instances = discoveryClient.getInstances(serviceId);
        
        for (ServiceInstance instance : instances) {
            Map<String, Object> instanceInfo = new HashMap<>();
            instanceInfo.put("instanceId", instance.getInstanceId());
            instanceInfo.put("serviceId", instance.getServiceId());
            instanceInfo.put("host", instance.getHost());
            instanceInfo.put("port", instance.getPort());
            instanceInfo.put("uri", instance.getUri().toString());
            instanceInfo.put("metadata", instance.getMetadata());
            instanceInfo.put("scheme", instance.getScheme());
            
            result.add(instanceInfo);
        }
        
        return result;
    }
} 